

/*

LPVOID VirtualAllocEx(
  [in]           HANDLE hProcess,
  [in, optional] LPVOID lpAddress,
  [in]           SIZE_T dwSize,
  [in]           DWORD  flAllocationType,
  [in]           DWORD  flProtect
);

BOOL VirtualFreeEx(
  [in] HANDLE hProcess,
  [in] LPVOID lpAddress,
  [in] SIZE_T dwSize,
  [in] DWORD  dwFreeType
);

BOOL WriteProcessMemory(
  [in]  HANDLE  hProcess,
  [in]  LPVOID  lpBaseAddress,
  [in]  LPCVOID lpBuffer,
  [in]  SIZE_T  nSize,
  [out] SIZE_T  *lpNumberOfBytesWritten
);

BOOL ReadProcessMemory(
  [in]  HANDLE  hProcess,
  [in]  LPCVOID lpBaseAddress,
  [out] LPVOID  lpBuffer,
  [in]  SIZE_T  nSize,
  [out] SIZE_T  *lpNumberOfBytesRead
);

HANDLE CreateRemoteThread(
  [in]  HANDLE                 hProcess,
  [in]  LPSECURITY_ATTRIBUTES  lpThreadAttributes,
  [in]  SIZE_T                 dwStackSize,
  [in]  LPTHREAD_START_ROUTINE lpStartAddress,
  [in]  LPVOID                 lpParameter,
  [in]  DWORD                  dwCreationFlags,
  [out] LPDWORD                lpThreadId
);

LPVOID VirtualAlloc(
  [in, optional] LPVOID lpAddress,
  [in]           SIZE_T dwSize,
  [in]           DWORD  flAllocationType,
  [in]           DWORD  flProtect
);
BOOL VirtualFree(
  [in] LPVOID lpAddress,
  [in] SIZE_T dwSize,
  [in] DWORD  dwFreeType
);

SIZE_T VirtualQuery(
  [in, optional] LPCVOID                   lpAddress,
  [out]          PMEMORY_BASIC_INFORMATION lpBuffer,
  [in]           SIZE_T                    dwLength
);

SIZE_T VirtualQueryEx(
  [in]           HANDLE                    hProcess,
  [in, optional] LPCVOID                   lpAddress,
  [out]          PMEMORY_BASIC_INFORMATION lpBuffer,
  [in]           SIZE_T                    dwLength
);

*/


#include<windows.h>
#include<iostream>

using namespace std;

// 要注入的代码
unsigned char code1[] = {
    0x90,  // NOP
    0xB8, 0x01, 0x00, 0x00, 0x00,  // MOV EAX, 1
    0xC3    // RET
};
// 模拟包含 printf 功能的简单代码片段
unsigned char code[] = {
    0x55,                     // push ebp
    0x89, 0xE5,               // mov ebp, esp
    0x83, 0xEC, 0x08,         // sub esp, 8
    0x68, 0x00, 0x00, 0x00, 0x00,  // push 地址，这里需要修改
    0x6A, 0x00,               // push 0
    0xE8, 0x00, 0x00, 0x00, 0x00,  // call printf 函数地址，这里需要修改
    0x83, 0xC4, 0x08,         // add esp, 8
    0x89, 0xEC,               // mov esp, ebp
    0x5D,                     // pop ebp
    0xC3                      // ret
};

int main(){
	
	cout << "input process ID: " << endl;
	DWORD processId;
	cin >> processId;
	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,processId);
	if(!hProcess){
		cerr << "OpenProcess failed. Error: " << GetLastError() << endl;
		return 1;
	}
	
	LPVOID remoteCode = VirtualAllocEx(hProcess,
										NULL,
										sizeof(code),
										MEM_COMMIT,
										PAGE_EXECUTE_READWRITE
										);
										
	if(!remoteCode){
		cerr << "VirtualAllocEx failed. Error: " << GetLastError() << endl;
		CloseHandle(remoteCode);
		return 1;
	}
	
	SIZE_T bytesWritten = 0;
	
	if(!WriteProcessMemory(hProcess,remoteCode,code,sizeof(code),&bytesWritten)){
		cerr << "WriteProcessMemory failed. Error: " << GetLastError() << endl;
		VirtualFreeEx(hProcess,remoteCode,0,MEM_RELEASE);
		CloseHandle(remoteCode);
		return 1;
	}
	
	HANDLE hThread = CreateRemoteThread(hProcess,
										NULL,
										0,
										(LPTHREAD_START_ROUTINE)remoteCode,
										NULL,
										0,
										NULL
										);
	if(!hThread){
		cerr << "CreateRemoteThread failed. Error: " << GetLastError() << endl;
		VirtualFreeEx(hProcess,remoteCode,0,MEM_RELEASE);
		CloseHandle(remoteCode);
		return 1;
	}
	
	WaitForSingleObject(hThread,INFINITE);
	
	unsigned char d[sizeof(code)];
	
	if(!ReadProcessMemory(hProcess,remoteCode,d,sizeof(d),NULL)){
		cerr << "ReadProcessMemory failed. Error: " << GetLastError() << endl;
		VirtualFreeEx(hProcess,remoteCode,0,MEM_RELEASE);
		CloseHandle(remoteCode);
		return 1;
	}
	
	for(int i=0;i<sizeof(d);i++){
		cout << hex << (int)d[i]; 
	}
	cout << endl;
	
	VirtualFreeEx(hProcess,remoteCode,0,MEM_RELEASE);
	CloseHandle(remoteCode);
	
	
	cout << "Over!" << endl;
	
	getchar();
	
	

	return 0;
}
